-- Lua Battle System - 战术AI

local Logger = require("utils.logger")
local AI = require("ai.ai_base")
local DecisionTreeModule = require("ai.decision_tree")

local TacticalAI = AI:new({
    -- 战术AI特有属性
    name = "Tactical AI",
    description = "具有战术决策能力的AI",
    
    -- 战术参数
    tactics = {
        priority_targeting = true, -- 是否优先攻击特定目标
        team_coordination = true, -- 是否考虑队伍协作
        terrain_awareness = false, -- 是否考虑地形因素
        enemy_weakness_awareness = true, -- 是否考虑敌人弱点
        resource_management = true -- 是否考虑资源管理
    },
    
    -- 战术权重
    tactic_weights = {
        damage_output = 0.3,
        team_survival = 0.3,
        resource_efficiency = 0.2,
        status_effects = 0.2
    },
    
    -- 敌人弱点数据库
    enemy_weaknesses = {},
    
    -- 决策树支持
    use_decision_tree = true,
    decision_trees = {
        attack = nil,
        defense = nil
    }
})

-- 战术AI构造函数
function TacticalAI:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    o:init()
    return o
end

-- 初始化战术AI
function TacticalAI:init()
    AI.init(self)
    self.tactics = {
        priority_targeting = true,
        team_coordination = true,
        terrain_awareness = false,
        enemy_weakness_awareness = true,
        resource_management = true
    }
    self.tactic_weights = {
        damage_output = 0.3,
        team_survival = 0.3,
        resource_efficiency = 0.2,
        status_effects = 0.2
    }
    self.enemy_weaknesses = {}
    
    -- 初始化决策树
    self.use_decision_tree = true
    self.decision_trees = {
        attack = nil,
        defense = nil
    }
    
    -- 构建决策树
    self:build_decision_trees()
    
    Logger.debug("战术AI初始化完成")
end

-- 构建决策树
function TacticalAI:build_decision_trees()
    local DecisionTree = DecisionTreeModule.DecisionTree
    
    -- 构建攻击决策树
    self.decision_trees.attack = DecisionTree:new({
        id = "attack_tree",
        name = "攻击决策树"
    })
    self.decision_trees.attack:build_attack_tree()
    
    -- 构建防御决策树
    self.decision_trees.defense = DecisionTree:new({
        id = "defense_tree",
        name = "防御决策树"
    })
    self.decision_trees.defense:build_defense_tree()
    
    Logger.info("战术AI决策树构建完成")
end

-- 分析战斗状态（扩展）
function TacticalAI:analyze_battle_state(character, battle_state)
    local analysis = AI.analyze_battle_state(self, character, battle_state)
    
    -- 分析敌人弱点
    if self.tactics.enemy_weakness_awareness then
        analysis.enemy_weaknesses = self:analyze_enemy_weaknesses(battle_state)
    end
    
    -- 分析队伍协作机会
    if self.tactics.team_coordination then
        analysis.coordination_opportunities = self:analyze_coordination_opportunities(character, battle_state)
    end
    
    -- 分析资源状况
    if self.tactics.resource_management then
        analysis.resource_status = self:analyze_resource_status(character, battle_state)
    end
    
    return analysis
end

-- 分析敌人弱点
function TacticalAI:analyze_enemy_weaknesses(battle_state)
    local weaknesses = {}
    
    for _, enemy in ipairs(battle_state.characters) do
        if enemy.team_id ~= battle_state.player_team_id then
            -- 这里简化处理，实际应该从数据库或配置文件中获取敌人弱点
            weaknesses[enemy.id] = {
                physical = math.random() > 0.5, -- 随机生成弱点
                magic = math.random() > 0.5,
                fire = math.random() > 0.5,
                ice = math.random() > 0.5,
                lightning = math.random() > 0.5,
                poison = math.random() > 0.5
            }
        end
    end
    
    return weaknesses
end

-- 分析队伍协作机会
function TacticalAI:analyze_coordination_opportunities(character, battle_state)
    local opportunities = {
        combo_attacks = {},
        support_opportunities = {}
    }
    
    -- 查找可以配合的队友
    for _, ally in ipairs(battle_state.characters) do
        if ally.team_id == character.team_id and ally.id ~= character.id and ally.is_alive then
            -- 检查队友是否有可以配合的技能
            for _, skill in ipairs(ally.skills) do
                if skill.type == "support" and skill:is_usable(ally) then
                    table.insert(opportunities.support_opportunities, {
                        ally = ally,
                        skill = skill
                    })
                end
            end
        end
    end
    
    return opportunities
end

-- 分析资源状况
function TacticalAI:analyze_resource_status(character, battle_state)
    local status = {
        mp_percentage = character.mp / character.max_mp,
        item_count = 0,
        skill_cooldowns = {}
    }
    
    -- 计算物品数量
    for _, count in pairs(character.items) do
        status.item_count = status.item_count + count
    end
    
    -- 记录技能冷却情况
    for _, skill in ipairs(character.skills) do
        status.skill_cooldowns[skill.id] = skill.current_cooldown
    end
    
    return status
end

-- 评估决策选项（扩展）
function TacticalAI:evaluate_options(character, battle_state, analysis, options)
    local evaluated_options = {}
    
    for _, option in ipairs(options) do
        local score = self:evaluate_tactical_option(character, battle_state, analysis, option)
        option.score = score
        table.insert(evaluated_options, option)
    end
    
    -- 按分数排序
    table.sort(evaluated_options, function(a, b) return a.score > b.score end)
    
    return evaluated_options
end

-- 评估战术决策选项
function TacticalAI:evaluate_tactical_option(character, battle_state, analysis, option)
    local score = 0
    
    -- 基础评分
    score = score + self:evaluate_damage_output(character, battle_state, analysis, option)
    score = score + self:evaluate_team_survival(character, battle_state, analysis, option)
    score = score + self:evaluate_resource_efficiency(character, battle_state, analysis, option)
    score = score + self:evaluate_status_effects(character, battle_state, analysis, option)
    
    -- 战术调整
    score = score + self:apply_tactical_adjustments(character, battle_state, analysis, option)
    
    -- 根据AI难度调整评分
    score = score * self:get_difficulty_multiplier()
    
    return score
end

-- 评估伤害输出
function TacticalAI:evaluate_damage_output(character, battle_state, analysis, option)
    local score = 0
    
    if option.type == "skill" and option.target.team_id ~= character.team_id then
        -- 计算预期伤害
        local expected_damage = option.skill:calculate_damage(character, option.target)
        
        -- 考虑敌人弱点
        if self.tactics.enemy_weakness_awareness and analysis.enemy_weaknesses[option.target.id] then
            local weaknesses = analysis.enemy_weaknesses[option.target.id]
            -- 这里简化处理，实际应该根据技能类型和敌人弱点计算加成
            if weaknesses[option.skill.type] then
                expected_damage = expected_damage * 1.5
            end
        end
        
        score = expected_damage * self.tactic_weights.damage_output
    end
    
    return score
end

-- 评估队伍生存能力
function TacticalAI:evaluate_team_survival(character, battle_state, analysis, option)
    local score = 0
    
    if option.type == "skill" and option.target.team_id == character.team_id then
        -- 计算预期治疗量
        local expected_healing = option.skill:calculate_healing(character, option.target)
        score = expected_healing * self.tactic_weights.team_survival
    end
    
    -- 考虑队友生命值
    if option.type == "skill" and option.target.team_id == character.team_id then
        local health_percentage = option.target.hp / option.target.max_hp
        if health_percentage < 0.3 then
            score = score * 2 -- 优先治疗低生命值队友
        end
    end
    
    return score
end

-- 评估资源效率
function TacticalAI:evaluate_resource_efficiency(character, battle_state, analysis, option)
    local score = 0
    
    if option.type == "skill" then
        -- 计算MP效率（伤害/MP消耗）
        if option.skill.cost.mp > 0 then
            local expected_damage = option.skill:calculate_damage(character, option.target)
            local efficiency = expected_damage / option.skill.cost.mp
            score = efficiency * self.tactic_weights.resource_efficiency
        else
            -- 无MP消耗的技能效率更高
            score = 10 * self.tactic_weights.resource_efficiency
        end
        
        -- 考虑MP剩余量
        if analysis.resource_status.mp_percentage < 0.2 then
            -- MP不足时优先使用低消耗技能
            score = score * (1 - option.skill.cost.mp / character.max_mp)
        end
    end
    
    return score
end

-- 评估状态效果
function TacticalAI:evaluate_status_effects(character, battle_state, analysis, option)
    local score = 0
    
    if option.type == "skill" then
        -- 计算状态效果价值
        local status_value = 0
        
        -- 对目标施加的状态效果
        for _, effect_info in ipairs(option.skill.status_effects.target) do
            status_value = status_value + self:get_status_effect_value(effect_info.id)
        end
        
        -- 对施法者施加的状态效果
        for _, effect_info in ipairs(option.skill.status_effects.caster) do
            status_value = status_value + self:get_status_effect_value(effect_info.id)
        end
        
        score = status_value * self.tactic_weights.status_effects
    end
    
    return score
end

-- 应用战术调整
function TacticalAI:apply_tactical_adjustments(character, battle_state, analysis, option)
    local adjustment = 0
    
    -- 优先攻击特定目标
    if self.tactics.priority_targeting then
        adjustment = adjustment + self:adjust_for_priority_targeting(character, battle_state, analysis, option)
    end
    
    -- 考虑队伍协作
    if self.tactics.team_coordination then
        adjustment = adjustment + self:adjust_for_team_coordination(character, battle_state, analysis, option)
    end
    
    -- 考虑资源管理
    if self.tactics.resource_management then
        adjustment = adjustment + self:adjust_for_resource_management(character, battle_state, analysis, option)
    end
    
    return adjustment
end

-- 调整优先攻击目标
function TacticalAI:adjust_for_priority_targeting(character, battle_state, analysis, option)
    local adjustment = 0
    
    if option.type == "skill" and option.target.team_id ~= character.team_id then
        -- 优先攻击治疗者或支援角色
        if option.target.magic_attack > option.target.attack then
            adjustment = adjustment + 50
        end
        
        -- 优先攻击低生命值敌人（补刀）
        local health_percentage = option.target.hp / option.target.max_hp
        if health_percentage < 0.2 then
            adjustment = adjustment + 100
        end
        
        -- 优先攻击最强敌人
        if option.target == analysis.strongest_enemy then
            adjustment = adjustment + 30
        end
    end
    
    return adjustment
end

-- 调整队伍协作
function TacticalAI:adjust_for_team_coordination(character, battle_state, analysis, option)
    local adjustment = 0
    
    -- 检查是否有队友可以配合
    for _, opportunity in ipairs(analysis.coordination_opportunities.support_opportunities) do
        if option.type == "skill" and option.target == opportunity.ally then
            adjustment = adjustment + 50
        end
    end
    
    return adjustment
end

-- 调整资源管理
function TacticalAI:adjust_for_resource_management(character, battle_state, analysis, option)
    local adjustment = 0
    
    -- MP不足时优先使用低消耗技能
    if analysis.resource_status.mp_percentage < 0.1 and option.type == "skill" then
        if option.skill.cost.mp == 0 then
            adjustment = adjustment + 100
        else
            adjustment = adjustment - 50
        end
    end
    
    return adjustment
end

-- 获取状态效果价值
function TacticalAI:get_status_effect_value(effect_id)
    local value_map = {
        burn = 20,
        freeze = 30,
        poison = 15,
        attack_buff = 25,
        defense_buff = 25,
        speed_buff = 20
    }
    
    return value_map[effect_id] or 10
end

-- 使用决策树做出决策
function TacticalAI:make_decision_with_tree(character, battle_state)
    -- 分析战斗状态
    local analysis = self:analyze_battle_state(character, battle_state)
    
    -- 根据战斗状态选择合适的决策树
    local decision_tree
    local health_percentage = character.hp / character.max_hp
    
    if health_percentage < 0.3 or #analysis.low_health_allies > 0 then
        -- 生命值低或有低生命值队友，使用防御决策树
        decision_tree = self.decision_trees.defense
    else
        -- 否则使用攻击决策树
        decision_tree = self.decision_trees.attack
    end
    
    -- 评估决策树
    local tree_decision = decision_tree:evaluate(character, battle_state)
    
    if not tree_decision then
        Logger.warn("决策树评估失败，使用默认决策逻辑")
        return AI.make_decision(self, character, battle_state)
    end
    
    Logger.debug("使用决策树做出决策: " .. tree_decision.type)
    
    -- 将决策树结果转换为标准决策格式
    local standard_decision = self:convert_tree_decision(tree_decision, character, battle_state, analysis)
    
    return standard_decision
end

-- 将决策树结果转换为标准决策格式
function TacticalAI:convert_tree_decision(tree_decision, character, battle_state, analysis)
    local standard_decision
    
    if tree_decision.type == "skill" then
        -- 技能决策
        local skill_strategy = tree_decision.strategy
        
        -- 根据策略选择技能和目标
        local skill, target = self:select_skill_and_target(character, battle_state, analysis, skill_strategy)
        
        if skill and target then
            standard_decision = {
                type = "skill",
                skill = skill,
                target = target,
                priority = tree_decision.priority
            }
        end
    elseif tree_decision.type == "item" then
        -- 物品决策
        local item_strategy = tree_decision.strategy
        
        -- 根据策略选择物品和目标
        local item, target = self:select_item_and_target(character, battle_state, analysis, item_strategy)
        
        if item and target then
            standard_decision = {
                type = "item",
                item = item,
                target = target,
                priority = tree_decision.priority
            }
        end
    elseif tree_decision.type == "defend" then
        -- 防御决策
        standard_decision = {
            type = "defend",
            target = character,
            priority = tree_decision.priority
        }
    end
    
    return standard_decision
end

-- 根据策略选择技能和目标
function TacticalAI:select_skill_and_target(character, battle_state, analysis, strategy)
    local skill = nil
    local target = nil
    
    if strategy == "attack_lowest_hp" then
        -- 攻击最低生命值敌人
        target = analysis.weakest_enemy
        
        -- 选择最高伤害技能
        skill = self:get_highest_damage_skill(character)
    elseif strategy == "attack_strongest_enemy" then
        -- 攻击最强敌人
        target = analysis.strongest_enemy
        
        -- 选择最高伤害技能
        skill = self:get_highest_damage_skill(character)
    elseif strategy == "use_control_skill" then
        -- 使用控制技能
        skill = self:get_control_skill(character)
        
        -- 选择最合适的目标
        target = self:get_best_control_target(character, battle_state, analysis)
    elseif strategy == "use_heal_skill" then
        -- 使用治疗技能
        skill = self:get_heal_skill(character)
        
        -- 选择最低生命值的目标
        if character.hp / character.max_hp < 0.5 then
            target = character
        else
            target = analysis.weakest_ally
        end
    elseif strategy == "heal_lowest_hp_ally" then
        -- 治疗最低生命值队友
        skill = self:get_heal_skill(character)
        target = analysis.weakest_ally
    elseif strategy == "use_support_skill" then
        -- 使用辅助技能
        skill = self:get_support_skill(character)
        target = analysis.strongest_ally
    else
        -- 默认使用普通攻击
        skill = self:get_basic_attack_skill(character)
        target = analysis.weakest_enemy
    end
    
    return skill, target
end

-- 根据策略选择物品和目标
function TacticalAI:select_item_and_target(character, battle_state, analysis, strategy)
    local item = nil
    local target = nil
    
    if strategy == "use_healing_item" then
        -- 使用治疗物品
        item = self:get_healing_item(character)
        
        -- 选择最低生命值的目标
        if character.hp / character.max_hp < 0.5 then
            target = character
        else
            target = analysis.weakest_ally
        end
    end
    
    return item, target
end

-- 获取最高伤害技能
function TacticalAI:get_highest_damage_skill(character)
    local highest_damage_skill = nil
    local highest_damage = 0
    
    for _, skill in ipairs(character.skills) do
        if skill:is_usable(character) and skill.damage.base > 0 then
            if skill.damage.base > highest_damage then
                highest_damage = skill.damage.base
                highest_damage_skill = skill
            end
        end
    end
    
    return highest_damage_skill
end

-- 获取控制技能
function TacticalAI:get_control_skill(character)
    for _, skill in ipairs(character.skills) do
        if skill:is_usable(character) and #skill.status_effects.target > 0 then
            return skill
        end
    end
    return nil
end

-- 获取治疗技能
function TacticalAI:get_heal_skill(character)
    for _, skill in ipairs(character.skills) do
        if skill:is_usable(character) and skill.healing.base > 0 then
            return skill
        end
    end
    return nil
end

-- 获取辅助技能
function TacticalAI:get_support_skill(character)
    for _, skill in ipairs(character.skills) do
        if skill:is_usable(character) and skill.type == "support" then
            return skill
        end
    end
    return nil
end

-- 获取基本攻击技能
function TacticalAI:get_basic_attack_skill(character)
    for _, skill in ipairs(character.skills) do
        if skill:is_usable(character) and skill.name == "普通攻击" then
            return skill
        end
    end
    return character.skills[1] -- 默认返回第一个技能
end

-- 获取治疗物品
function TacticalAI:get_healing_item(character)
    local ItemManager = require("items.item_manager")
    
    for item_id, quantity in pairs(character.items) do
        if quantity > 0 then
            local item = ItemManager:get_item(item_id)
            if item and item.type == "consumable" and item.effects.healing then
                return item
            end
        end
    end
    return nil
end

-- 获取最佳控制目标
function TacticalAI:get_best_control_target(character, battle_state, analysis)
    -- 优先控制最强敌人
    return analysis.strongest_enemy
end

-- 重写make_decision方法
function TacticalAI:make_decision(character, battle_state)
    if self.use_decision_tree then
        return self:make_decision_with_tree(character, battle_state)
    else
        return AI.make_decision(self, character, battle_state)
    end
end

-- 导出模块
return TacticalAI